package com.sangeng.ss.fillter;

import com.sangeng.ss.config.RedisCache;
import com.sangeng.ss.domain.LoginUser;
import com.sangeng.ss.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author ：xxx
 * @description：TODO
 * @date ：2024/03/01 14:07
 */
@Component
public class JwtAuthorityFilter extends OncePerRequestFilter {
    @Autowired
    private RedisCache redisCache;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        // 取出token
        String token = httpServletRequest.getHeader("token");
        // 校验
        if (!StringUtils.hasLength(token)) {
            filterChain.doFilter(httpServletRequest, httpServletResponse);
            return;
        }
        String userId = null;
        // 解析token
        try {
            Claims claims = JwtUtil.parseJWT(token);
            userId = claims.getSubject();
        } catch (Exception e) {
            e.printStackTrace();
//            throw new AccessDeniedException("token解析异常");
            filterChain.doFilter(httpServletRequest, httpServletResponse);
            return;
        }
        // redis中取出
        LoginUser loginUser = redisCache.getCacheObject("sys:user:" + userId);
        if (loginUser == null) {
            filterChain.doFilter(httpServletRequest, httpServletResponse);
            return;
//            throw new AccessDeniedException("用户未认证");
        }

        // 存入contextHolder已完成认证

//        List<SimpleGrantedAuthority> authorities = Stream.of("aaa", "bbb", "test", "hello").map(SimpleGrantedAuthority::new).collect(Collectors.toList());

        List<SimpleGrantedAuthority> authorities = loginUser.getPermissions().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());

        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginUser, null, authorities);
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

        // 放行
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}
